package com.hmdp.service.impl;

import cn.hutool.json.JSONUtil;
import com.hmdp.dto.Result;
import com.hmdp.entity.ShopType;
import com.hmdp.mapper.ShopTypeMapper;
import com.hmdp.service.IShopTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.utils.RedisConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {
    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public Result queryType() {
        //从redis中根据前缀获取全部的key
        Set<String> keys = stringRedisTemplate.keys(RedisConstants.SHOP_GEO_KEY + "*");
        //用于接受所有的类型数据
        List<ShopType> shopTypes = null;
        //如果可以缓存里面存在key，就根据这些key去redis获取这些类型数据
        if (keys != null && !keys.isEmpty()) {
            shopTypes = keys.stream().map(
                    key -> JSONUtil.toBean(stringRedisTemplate.opsForValue().get(key), ShopType.class)
            ).collect(Collectors.toList());
            return Result.ok(shopTypes);
        }
        //从数据库中获取类型数据
        shopTypes = query().orderByAsc("sort").list();
        //一般在测试阶段才可能是空的，不过也有可能会是查询语句的错误导致
        if (shopTypes.isEmpty())
            return Result.fail("不存在任何类型");
        //把数据全部载入缓存
        shopTypes.forEach(
                shopType -> stringRedisTemplate.opsForValue().set(
                        RedisConstants.SHOP_GEO_KEY + shopType.getId(),
                        JSONUtil.toJsonStr(shopType),
                        Duration.ofHours(RedisConstants.SHOP_TYPE_TTL)
                )
        );
        return Result.ok(shopTypes);
    }
}
